/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023.
 * Description: rtos irq priority division feature functions
 * Author: huyizhou
 * Create: 2023-09-14
 */

#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/irqchip/arm-gic.h>
#ifdef CONFIG_CORTEX_A15
#include <asm/irq.h>
#include <linux/hal/hisilicon.h>
#endif

#include "irq-gic-common.h"

void gic_irq_pri_init(void __iomem *base)
{
	int i;
#ifdef CONFIG_CORTEX_A15
	volatile unsigned int value;

	/*
	 * Set priority on PPI and SGI interrupts for 1381
	 *                 id       priority
	 *                 0~5       0x10
	 *                 6~15      0xb0
	 *                 16~31     0xa0
	 * ID 0~5's priority is 0x10 and ID6~15's priority is 0xb0
	 */
	writel_relaxed(0x10101010, base + GIC_DIST_PRI + 0 * 4 / 4);
	writel_relaxed(0xb0b01010, base + GIC_DIST_PRI + 4 * 4 / 4);
	writel_relaxed(0xb0b0b0b0, base + GIC_DIST_PRI + 8 * 4 / 4);
	writel_relaxed(0xb0b0b0b0, base + GIC_DIST_PRI + 12 * 4 / 4);
	/*
	 * PPI pri, current set all slave cores' ppi to 0xb0, ctrl
	 * field don't use localtimer currently. need to fix
	 */

	/*
	 * ID16~31's priority is 0xa0
	 */
	for (i = 16; i < 32; i += 4)
		writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);

	/* local timer interrupt priority set */
	value = readl_relaxed(base + GIC_DIST_PRI + (IRQ_LOCALTIMER / 4) * 4);
	value &= ~(0xff << ((IRQ_LOCALTIMER % 4) * 8));
	value |= (0xb0 << ((IRQ_LOCALTIMER % 4) * 8));
	writel_relaxed(value, base + GIC_DIST_PRI + (IRQ_LOCALTIMER / 4) * 4);

	/* N2N pri */
	for (i = 384; i < max_nr_irqs; i += 4)
		writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
#else

	/*
	 * Set priority on PPI and SGI interrupts
	 *                 id       priority
	 *                 0~5       0x20
	 *                 6~15      0x60
	 *                 16~31     0x40
	 * ID 0~5's priority is 0x20 and ID6~7's priority is 0x60
	 */
	writel_relaxed(0x20202020, base + GIC_DIST_PRI);
	writel_relaxed(0x60602020, base + GIC_DIST_PRI + 4);

	/*
	 * ID8~15's priority is 0x60
	 */
	writel_relaxed(0x60606060, base + GIC_DIST_PRI + 8);
	writel_relaxed(0x60606060, base + GIC_DIST_PRI + 12);

	/*
	 * ID16~31's priority is 0x40
	 */
	for (i = 16; i < 32; i += 4)
		writel_relaxed(0x40404040, base + GIC_DIST_PRI + i * 4 / 4);
#endif /* CONFIG_CORTEX_A15 */
}
